﻿(
    function ( $, ko ) {
        var i = function ( t ) {
            var i = $( t );
            return $( document ).find( t ).length == 0 && $( parent.document ).find( t ).length > 0 && ( i = parent.$( t ) ),
        i
        };
        ko.createEasyUiGridBindings = function ( pro ) {
            return {
                update: function ( element, valueAccessor ) {
                    // declare elem, value and databind;
                    var gridControl = $( element ),
                        grid = valueAccessor(),
                        value = ko.toJS( grid ),
                        bindData = function ( params ) {
                            if ( !params || typeof ( params ) != "object" ) params = ko.toJS( valueAccessor() ).queryParams;

                            var opts = gridControl.datagrid( "options" );

                            if ( opts.pagination ) {
                                var pagerOption = gridControl[pro]( "getPager" ).pagination( "options" );
                                $.extend( params, {
                                    pageNumber: pagerOption.pageNumber,
                                    pageSize: pagerOption.pageSize
                                } );
                                if ( opts ) {
                                    opts.pageNumber = pagerOption.pageNumber;
                                    opts.pageSize = pagerOption.pageSize;
                                }
                            }

                            if ( opts && opts.sortName ) {
                                $.extend( params, {
                                    sortName: opts.sortName,
                                    sortOrder: opts.sortOrder
                                } );
                            }

                            $.ajax( {
                                type: "GET",
                                url: value.url,
                                data: params,
                                success: function ( data ) {
                                    gridControl[pro]( "loadData", data );
                                }
                            } );
                        };
                    // if elem.datagrid is undefined then init it and init the sort and selectpage event;
                    if ( gridControl.data( pro ) ) {
                        // bind data
                        bindData( value.queryParams );
                    } else {
                        var options = {
                            pagination: true,
                            rownumbers: true,
                            customLoad: false,
                            method: 'GET',
                            singleSelect: true,
                            autoRowHeight: false,
                            fit: true,
                            pageSize: 10,
                            remoteSort: true
                        };
                        options = $.extend( options, value );
                        //-- url will cause load method of datagrid control, but we want load data manually, os delete it before init datagrid options as below;
                        delete options.url,
                        grid[pro] = function () { return gridControl[pro].apply( gridControl, arguments ); },
                        options.onSortColumn = bindData,
                        gridControl[pro]( options ),
                        gridControl[pro]( "getPager" ).pagination( {
                            pageList: [5, 10, 20],
                            onSelectPage: bindData
                        } ),
                        bindData( value.queryParams );
                    }
                }
            };
        },
        ko.bindingHandlers.datagrid = ko.createEasyUiGridBindings( "datagrid" ),
        ko.bindingViewModel = function ( vm, elem ) {
            $.parser.onComplete = function () {
                ko.applyBindings( vm, elem || document.body );
            };
        },
        ko.creatEasyuiValueBindings = function ( elemConfig ) {
            elemConfig = $.extend( {
                type: "",
                event: "",
                getter: "getValue",
                setter: "setValue",
                fix: $.noop,
                formatter: function ( n ) {
                    return n
                }
            }, elemConfig );

            var handle = {
                init: function ( elem, valueAccessor ) {
                    var elemControl = $( elem ),
                        event = elemControl[elemConfig.type]( "options" )[elemConfig.event],
                        eventConfig = {};

                    eventConfig[elemConfig.event] = function () {
                        event.apply( $, arguments );
                        var latestValue = elemControl[elemConfig.type]( elemConfig.getter );
                        valueAccessor()( latestValue );
                        //if (u() == null) throw "viewModel中没有页面绑定的字段";
                        //u()(ko);
                    },
                    ko.utils.domNodeDisposal.addDisposeCallback( elem, function () {
                        elemControl[elemConfig.type]( "destroy" )
                    } ),
                    elemConfig.fix( elem, valueAccessor ),
                    elemControl[elemConfig.type]( eventConfig );
                },
                update: function ( elem, valueAccessor ) {
                    value = ko.utils.unwrapObservable( valueAccessor() ),
                    $( elem )[elemConfig.type]( elemConfig.setter, elemConfig.formatter( value ) );
                }
            };
            ko.bindingHandlers[elemConfig.type + "Value"] = handle;
        },
        ko.creatEasyuiValueBindings( {
            type: "numberspinner",
            event: "onChange",
            fix: function ( elem ) {
                $( elem ).width( $( elem ).width() + 20 );
            }
        } ),
        ko.creatEasyuiValueBindings( {
            type: "numberbox",
            event: "onChange"
        } );
    } ( jQuery, ko )
)